package pl.org.lutra.planner.gui.table;

import pl.org.lutra.planner.Planner;
import pl.org.lutra.planner.gui.resources.Text;
import pl.org.lutra.planner.model.data.Dive;
import pl.org.lutra.planner.model.data.DiveSegment;
import pl.org.lutra.planner.model.input.Input;
import pl.org.lutra.planner.model.util.DiveOperator;

public class DiveTableModel extends PlannerTableModel<DiveSegment> {
    private static final long serialVersionUID = 598263953377853050L;
    
    private Input input = Planner.getInstance().getInput();
    private DiveOperator operator = new DiveOperator();
    
    public DiveTableModel() {
        Dive dive = input.getDive();
        operator.setDive(dive);
        setSegments(dive.getSegments());
    }
    
    @Override
    protected DiveColumn[] createColumns() {
        return new DiveColumn[] {DiveColumn.START_DEPTH, DiveColumn.TARGET_DEPTH, DiveColumn.TIME,
        DiveColumn.RUNTIME};
    }
    
    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return columnIndex > 0;
    }
    
    @Override
    public void setValueAt(Object value, int row, int column) {
        ((DiveColumn) columns[column]).setValue(operator, row, value);
        fireTableDataChanged();
    }
    
    public void addRow() {
        boolean success = operator.addSegment();
        
        if (success) {
            int newRowIndex = segments.size() - 1;
            fireTableRowsInserted(newRowIndex, newRowIndex);
        }
    }
    
    public void deleteRow(int row) {
        if (row < 0) {
            row = segments.size() - 1;
        }
        
        boolean success = operator.deleteSegment(row);
        
        if (success) {
            fireTableRowsDeleted(row, row);
        }
    }
    
    enum DiveColumn implements PlannerColumn<DiveSegment> {
        START_DEPTH("column.startDepth") {
            @Override
            public Object getValue(DiveSegment segment) {
                return segment.getStartDepth();
            }
            
            @Override
            public void setValue(DiveOperator operator, int row, Object value) {
            }
        },
        TARGET_DEPTH("column.targetDepth") {
            @Override
            public Object getValue(DiveSegment segment) {
                return segment.getTargetDepth();
            }
            
            @Override
            public void setValue(DiveOperator operator, int row, Object value) {
                operator.setTargetDepth(row, Float.parseFloat((String) value));
            }
        },
        TIME("column.time") {
            @Override
            public Object getValue(DiveSegment segment) {
                return segment.getTime();
            }
            
            @Override
            public void setValue(DiveOperator operator, int row, Object value) {
                operator.setTime(row, Float.parseFloat((String) value));
            }
        },
        RUNTIME("column.runtime") {
            @Override
            public Object getValue(DiveSegment segment) {
                return segment.getRuntime();
            }
            
            @Override
            public void setValue(DiveOperator operator, int row, Object value) {
                operator.setRuntime(row, Float.parseFloat((String) value));
            }
        };
        
        private String key;
        
        private DiveColumn(String key) {
            this.key = key;
        }
        
        @Override
        public String getLabel() {
            return Text.get(key);
        }
        
        public abstract void setValue(DiveOperator operator, int row, Object value);
    }
}
